package widget.utils;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.ref.WeakReference;

import library.image.ImageUtils;
import library.logger.Logger;


/**
 * Created by Mr.Fan on 2016-5-13.
 */
public class Tips {
    private WeakReference<Context> reference;

    private Object icon;
    private int duration = Toast.LENGTH_SHORT;
    private int gravity = Gravity.TOP;

    private Context getContext() {
        return reference != null ? reference.get() : null;
    }

    private Tips(Context context) {
        reference = new WeakReference<>(context);
    }

    public static Tips obtain(Context context) {
        return new Tips(context);
    }

    public Tips gravity(int gravity) {
        this.gravity = gravity;
        return this;
    }

    public Tips icon(int resId) {
        this.icon = resId;
        return this;
    }

    public Tips icon(Drawable drawable) {
        this.icon = drawable;
        return this;
    }

    public Tips duration(Integer duration) {
        if (duration != null)
            this.duration = duration.intValue();
        return this;
    }

    public Tips duration(Long duration) {
        if (duration != null)
            this.duration = duration.intValue();
        return this;
    }

    public Tips duration(Float duration) {
        if (duration != null)
            this.duration = duration.intValue();
        return this;
    }

    public Tips duration(Double duration) {
        if (duration != null)
            this.duration = duration.intValue();
        return this;
    }

    private void toast(final Context context, final Drawable drawable, final String msg) {
        try {
            ToastHandler toastHandler = new ToastHandler(Looper.getMainLooper(),
                    context, msg, duration, drawable, gravity);
            toastHandler.sendEmptyMessage(0);
        } catch (Exception e) {
            Logger.debug(e);
        }
    }

    public void toast(String fmt, Object... args) {
        Context context = getContext();
        if (context == null)
            return;
        String msg = null;
        try {
            msg = String.format(fmt, args);
        } catch (Exception e) {
            msg = fmt;
        }
        if (context != null && !TextUtils.isEmpty(msg))
            toast(context, null, msg);
    }

    public void warn(String fmt, Object... args) {
        Context context = getContext();
        if (context == null)
            return;
        String msg = null;
        try {
            msg = String.format(fmt, args);
        } catch (Exception e) {
            msg = fmt;
        }
        if (context != null && !TextUtils.isEmpty(msg)) {
            Drawable drawable = null;
            if (icon == null)
                icon = ImageUtils.obtain(context).assets("widget/images/icon/warnning.png");
            if (icon instanceof Drawable) {
                drawable = (Drawable) icon;
            } else if (icon instanceof Integer) {
                try {
                    int resId = Integer.parseInt(String.valueOf(icon));
                    drawable = context.getResources().getDrawable(resId);
                } catch (Exception e) {
                    Logger.debug(e);
                }
            }
            gravity(Gravity.BOTTOM);
            toast(context, drawable, msg);
        }
    }

    public static void toast(Context context, String fmt, Object... args) {
        obtain(context).toast(fmt, args);
    }

    public static void warn(Context context, String fmt, Object... args) {
        obtain(context).warn(fmt, args);
    }


    private static int dp2px(Context context, int dp) {
        return (int) (context.getResources().getDisplayMetrics().density * dp + 0.5f);
    }

    private static View getView(Context context, Drawable icon, String msg) {
        final LinearLayout ll = new LinearLayout(context);
        final ImageView iv = new ImageView(context);

        final TextView tv = new TextView(context);
        final int height = (int) tv.getTextSize();
        final int padding = dp2px(context, 8);
        LinearLayout.LayoutParams lp_iv = new LinearLayout.LayoutParams(height * 3 / 2, height);
        LinearLayout.LayoutParams lp_tv = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lp_iv.rightMargin = lp_iv.width / 3;
        tv.setTextSize(12);
        tv.setText(msg);
        tv.setTextColor(Color.WHITE);
        iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
        if (icon != null)
            iv.setImageDrawable(icon);
        else
            iv.setVisibility(View.GONE);

        ll.setBackgroundDrawable(getBackground(context));
        ll.setPadding(padding, padding, padding, padding);
        ll.setOrientation(LinearLayout.HORIZONTAL);
        ll.addView(iv, lp_iv);
        ll.addView(tv, lp_tv);
        ll.setGravity(Gravity.CENTER);

        final LinearLayout container = new LinearLayout(context);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        container.setPadding(padding, padding, padding, padding);
        container.setLayoutParams(lp);
        container.addView(ll, lp);
        return container;
    }

    private static Drawable getBackground(Context context) {
        GradientDrawable gd = new GradientDrawable();
        gd.setColor(Color.parseColor("#99444444"));
        gd.setCornerRadius(dp2px(context, 2));
        return gd;
    }

    private static int marginTop(Context context) {
        int actionBarHeight = 0;
        TypedValue typedValue = new TypedValue();
        if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) {
            actionBarHeight = TypedValue.complexToDimensionPixelSize(typedValue.data,
                    context.getResources().getDisplayMetrics());
        }
        if (actionBarHeight == 0)
            actionBarHeight = dp2px(context, 56);
        else {
            actionBarHeight += dp2px(context, 4);
        }
        return actionBarHeight;
    }


    private static class ToastHandler extends Handler {
        private final WeakReference<Context> reference;
        private final String message;
        private final int duration;
        private final Drawable drawable;
        private final int gravity;

        private ToastHandler(Looper looper, Context context, String msg, int duration, Drawable drawable, int gravity) {
            super(looper);
            this.reference = new WeakReference<>(context);
            this.message = msg;
            this.duration = duration;
            this.drawable = drawable;
            this.gravity = gravity;
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            try {
                Context context = reference != null ? reference.get() : null;
                if (context == null)
                    return;
                Toast toast = new Toast(context);//Toast.makeText(context, msg, Toast.LENGTH_LONG);
                toast.setView(getView(context, drawable, message));
                toast.setDuration(duration);

                int margin = 0;

                if (gravity == Gravity.TOP) {
                    margin = marginTop(context);
                } else if (gravity == Gravity.BOTTOM) {
                    margin = dp2px(context, 24);
                }
                toast.setGravity(gravity | Gravity.FILL_HORIZONTAL, 0, margin);

                toast.show();
            } catch (Exception e) {
                Logger.debug(e);
            }
        }
    }
}
